package v1

import (
	"context"
	"encoding/hex"
	"fmt"
	"github.com/gin-gonic/gin"
	"gitlab.local/backend/proto/dto"
	"go-micro.dev/v4/client"
	"manager/bll"
	"manager/client/broker"
	"manager/client/grpc"
	"manager/lib/trace_log"
	"manager/utils"
	"sync"
	"time"
)

var TestExample = &testExample{}

func init() {
	// 注册路由
	RegisterRouter(TestExample)
}

type testExample struct{}

// Init 初始化路由
func (a *testExample) Init(r *gin.RouterGroup) {
	// web 路由
	g := r.Group("/test")
	{
		g.POST("/shadow", a.testShadow)
		g.POST("/device_req", a.binaryReq)
	}
}

type DeviceBinaryRequest struct {
	Sn  string `json:"sn"`
	Hex string `json:"hex"`
}

func (a *testExample) binaryReq(c *gin.Context) {
	var (
		in  = &DeviceBinaryRequest{}
		err error
		rsp *dto.BinaryRequestReply
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	trace_log.DebugLogger(in.Sn, "binaryReq 请求:", fmt.Sprintf("%X", in.Hex))
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()
	bytes, _ := hex.DecodeString(in.Hex)
	rsp, err = grpc.Cmd.BinaryReq(ctx, &dto.BinaryRequest{
		Sn:  in.Sn,
		Hex: bytes,
	}, func(options *client.CallOptions) {
		options.Address = []string{bll.GetSignalAddressBySn(in.Sn)}
	})
	if err != nil {
		c.Error(err)
		return
	}

	var data string
	if rsp != nil && rsp.Response != nil {
		data = fmt.Sprintf("%X", rsp.Response)
	}

	utils.ResponseOk(c, data)
	return
}

// testShadow 测试影子
func (a *testExample) testShadow(c *gin.Context) {
	fmt.Println("-------------------------------- testShadow 压测开始 --------------------------------")
	type Request struct {
		RequestType    int `json:"request_type"`    // 1 查询 2 更新
		Count          int `json:"count"`           // 次数
		GoroutineCount int `json:"goroutine_count"` // 并发数
	}

	var (
		in  = &Request{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	var waitGroup sync.WaitGroup
	for i := 0; i < in.GoroutineCount; i++ {
		go func() {
			waitGroup.Add(1)
			defer waitGroup.Done()
			sn := utils.Generate(time.Now())
			for j := 0; j < in.Count; j++ {
				if in.RequestType == 1 {
					grpc.SCmd.GetShadowAttributes(c, &dto.GetShadowAttributesRequest{
						DeviceName: sn,
					})
				}

				if in.RequestType == 2 {
					// 更新
					broker.Consumer.SyncDeviceInfoToShadow(sn, dto.EnUpdateType_ATTRIBUTE, map[string]interface{}{
						"test": "test",
					})

					grpc.SCmd.GetShadowAttributes(c, &dto.GetShadowAttributesRequest{
						DeviceName: sn,
					})
				}
			}
		}()
	}

	waitGroup.Wait()

	fmt.Println("-------------------------------- testShadow 压测结束 --------------------------------")

}
